var DxfParser = require('../');
var fs = require('fs');
var path = require('path');
var RLines = require('./renderLines');

var DXF_FILE_PATH = path.join(__dirname, 'data', 'build.dxf');
var OUTPUT_FILE_NAME = "cad.json";

var fileStream = fs.createReadStream(DXF_FILE_PATH, { encoding: 'utf8' });

var parser = new DxfParser();
var res_struct = [],max = {x:0,y:0},min = {},res_color = {},res_build = []

var color = {
    '1271604': 'DN100',
    '16711935': 'DN150',
    '6562149': 'DN200',
    '255': 'DN300',
    '16711680': 'DN400',
}
//var layers = ['ASSIST','corrs','DXG','DLDW','TKDMTZ','GCD','GXYZ','ntk','SXSS','TK','wtk','ZBTZ']
var layers = ['build','line']
parser.parseStream(fileStream, function(err, dxf) {
    if(err) return console.error(err.stack);
    //fs.writeFileSync(OUTPUT_FILE_NAME, JSON.stringify(dxf, null, 3));
    console.log(dxf.entities.length)
    dxf.entities = resetData(dxf)
    dxf.blocks = []
    var res = {}
    dxf.entities.map(function(e){
        if(!res[e.layer]){
            res[e.layer] = 0
        }
        res[e.layer] ++

    })
    var stc = {
        points:[],
        indices:[],
        colors:[],
        type:'LINE',
        flag:'block',
        layer:'建筑及道路'
    }
    //console.log('res_build',res_build.length)
    res_build.map(function(e){
        if(e.shape){
            e.vertices = e.vertices.concat([e.vertices[0]])
        }
        e.vertices.map(function(p,i){
            if (i == 0 || i == e.vertices.length - 1) {
                stc.indices.push(stc.points.length / 3)
            }
            else {
                stc.indices.push(stc.points.length  / 3, stc.points.length / 3)
            }
            stc.points.push(p.x, p.y, 0)
        })
    }) 
    //console.log('stc',stc.indices.length,stc.points.length)
    dxf.entities.push(stc)
    //console.log(res)
    var tlayers = {
        '建筑及道路':{color:dxf.tables.layer.layers['build'].color,name:'建筑及道路'},
    }
    for(var key in color){
        tlayers[color[key]] = {color:key,name:color[key],b:true}
    }
    dxf.tables.layer.layers = tlayers

    res_struct = res_struct.map(function(e,i){
        e.userData = {id:i,chr:[],layer:e.layer}
        return e
    })
    rlines = new RLines(0.1,res_struct)
    rlines.action()
    dxf.sys = {start:'0',points:[],dn:400}

    dxf.sys.lines = rlines.lines.map(function(e,i){
        var struct ={flag:'fat'},chr = [],len = 0
        struct.type = e.type
        struct.layer = e.layer
        struct.userData = e.userData

        for(var index = 0;index < e.vertices.length - 1;index ++){
            len += Math.sqrt(Math.pow(e.vertices[index].x - e.vertices[index + 1].x, 2) + Math.pow(e.vertices[index].y - e.vertices[index +  1].y, 2))
        }
        struct.userData.len = len 

        rlines.lines.map(function(l){
            if(e.userData.chr.indexOf(l.userData.id) >= 0){
                chr.push({dn:parseInt(l.layer.replace('DN','')),id:l.userData.id})
            }
        })
        struct.userData.chr = chr

        struct.vertices = []
        e.vertices.map(function(p){
            struct.vertices.push(p.x, p.y, 0)
        })

        if(e.userData && e.userData.p){
            if(e.userData.p[0] >= 2){
              dxf.sys.points.push(e.vertices[0])
            }
            if(e.userData.p[1] >= 2){
              dxf.sys.points.push(e.vertices[e.vertices.length - 1])
            }
        }
        return struct
    })
    
    //dxf.entities = dxf.entities.concat(res_build)
    
    console.log(dxf.entities.length)
    console.log(res_color)
    fs.writeFileSync(OUTPUT_FILE_NAME, JSON.stringify(dxf));
    console.log('Done writing output to ' + OUTPUT_FILE_NAME);
});
function getBlockEntity(dm,data,p){
    var res = [],po = {x:0,y:0,z:0}
    var en = dm
    switch(en.type){
        case 'DIMENSION':
            if(!en.view && en.position){
                en.view = en.position
            }
            console.log(en.block)
            // for(var i = 0;i < data.blocks[en.block].entities.length;i++){
            //     data.blocks[en.block].entities[i].view = en.view
            //     res = res.concat(getBlockEntity(data.blocks[en.block].entities[i],data))
            // }
            break;
        case 'INSERT':
        //console.log(en.type)
                if(en.position){
                    po.x = en.position.x + p.x
                    po.y = en.position.y + p.y
                    po.z = en.position.z + p.z
                }
                else{
                    po = p
                }
              
                for(var i = 0;i < data.blocks[en.name].entities.length;i++){
                    var temp = data.blocks[en.name].entities[i]
                    if(temp.flag){
                        temp.flag += 1
                    }
                    else{
                        temp.flag = 1
                    }
                    
                    res = res.concat(getBlockEntity(temp,data,po))
                }
            break;
        default:
            if(!en.flag || (en.flag && en.flag == 1)){
                if(layers.indexOf(en.layer) >= 0){
                    if(en.vertices){
                        en.vertices = en.vertices.map(function(e){
                            e.x += p.x
                            e.y += p.y
                            e.z += p.z
                            return e
                        })
                    }
                    else if(en.startPoint ){
                        en.startPoint.x += p.x
                        en.startPoint.y += p.y
                        en.startPoint.z += p.z
                    }
                    else if(en.position && en.type == "POINT"){
                        en.position.x += p.x
                        en.position.y += p.y
                        en.position.z += p.z
                    }
                    else if(en.center){
                        en.center.x += p.x
                        en.center.y += p.y
                        en.center.z += p.z
                    }
                    //res_struct[en.type].push(en)
                    switch(en.type){
                        case 'LWPOLYLINE':
                        case 'LINE':
                        case 'POLYLINE':
                            if(en.color && color[en.color]){
                                en.layer = color[en.color]
                                res_struct.push(en)
                                
                            }
                            else{
                                en.layer = '建筑及道路'
                                if(en.color){
                                    if(!res_color[en.color]){
                                        res_color[en.color] = 0
                                    }
                                    res_color[en.color] ++
                                }
                                res_build.push(en)
                            }
                            break;
                        case 'TEXT':
                        case 'MTEXT':
                            //en.layer = '标注标识'
                            //res.push(en)
                            break;
                        default:
                            en.layer = '建筑及道路'
                            res.push(en)
                            break;
                    }
                    //res.push(en)
                }
            }
            break;
    }
    return res
}
function resetData(ob){
    var res = [],point = {x:0,y:0,z:0}
    ob.entities.map(function(e){
        res = res.concat(getBlockEntity(e,ob,point))
    })
    console.log(res.length)
    return res
}
//线段连接，将同层的线条连接在一起
    function check_dis(a,b){
        var flag = false;
        var dis = Math.sqrt(Math.pow(a.x - b.x,2) + Math.pow(a.y - b.y,2));
        
        if(dis == 0){
            flag =  true;
        }
        return flag;
    }
    function check_sam(a,b){
        var flag = true;
        if(a.length == b.length){
            a.map(function(e,i){
                if(!(e.x == b[i].x && e.y == b[i].y)){
                    flag = false
                }
            })
        }
        else{
            flag = false
        }
        return flag;
    }
    function array_contain(arr, obj){
        var num = 0,arr_e = arr.length - 1,obj_e = obj.length - 1;
        //console.log(arr, obj)
        if(check_dis(arr[arr_e],obj[0])){
            num = 1;
            if(check_sam(arr.reverse(), obj)){
                num = 5
            }
        }
        else if(check_dis(arr[arr_e],obj[obj_e])){
            num = 2;
            if(check_sam(arr, obj)){
                num = 5
            }
        }
        else if(check_dis(arr[0],obj[0])){
            num = 4;
            if(check_sam(arr, obj)){
                num = 5
            }
        }
        else if(check_dis(arr[0],obj[obj_e])){
            num = 3;
            if(check_sam(arr, obj.reverse())){
                num = 5
            }
        }
        return num;
    }
    function renderEntity(arr){
        var res = [],len = arr.length
        while(arr.length > 0){
            var result = [],enti = arr[0]
            console.log(arr.length,res.length)
            arr.map(function(en,index){
                if(index > 0){
                    if(enti.layer != en.layer){
                        result.push(en);
                    }
                    else{
                        switch(array_contain(enti.vertices,en.vertices)){
                            case 0:
                                result.push(en);
                                break;
                            case 1:
                                enti.vertices = enti.vertices.concat(en.vertices.filter(function(e,i){return i > 0;}));
                                break;
                            case 2:
                                enti.vertices = enti.vertices.concat(en.vertices.reverse().filter(function(e,i){return i > 0;}));
                                break;
                            case 3:
                                enti.vertices = en.vertices.concat(enti.vertices.filter(function(e,i){return i > 0;}));
                                break;
                            case 4:
                                enti.vertices = (en.vertices.reverse()).concat(enti.vertices.filter(function(e,i){return i > 0;}));
                                break;
                        }
                    }
                }
            })
            arr = result
            res.push(enti)
        }
        if(res.length == len ){
            return res
        }
        else{
            return renderEntity(res)
        }
        
    }